package com.dc.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dc.common.DateUtil;
import com.dc.common.ResponseResultVO;
import com.dc.constat.SystemConfigConstant;
import com.dc.constat.SystemConstant;
import com.dc.entity.SysRole;
import com.dc.entity.SysUser;
import com.dc.entity.SysUserRole;
import com.dc.entity.ro.SysUserLoginRO;
import com.dc.feign.BaseApiServiceFeign;
import com.dc.mapper.SysRoleMapper;
import com.dc.mapper.SysUserMapper;
import com.dc.mapper.SysUserRoleMapper;
import com.dc.model.ShiftManagement;
import com.dc.service.SysConfigService;
import com.dc.service.SysUserLoginService;
import com.dc.util.*;
import com.dc.vo.SysRoleVO;
import com.dc.vo.SysUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysUserLoginServiceImpl implements SysUserLoginService {

    @Resource
    SysUserMapper sysUserMapper;

    @Resource
    RedisUtil redisUtil;

    @Resource
    SysConfigService sysConfigService;

    @Resource
    VerifyCodeUtil verifyCodeUtil;

    @Resource
    SysUserRoleMapper userRoleMapper;

    @Resource
    SysRoleMapper sysRoleMapper;

    @Resource
    TokenUtil tokenUtil;

    @Resource
    private BaseApiServiceFeign baseApiServiceFeign;


    @Override
    public ResponseResultVO logout() {
        SysUser sysUser = sysUserMapper.selectById(UserUtil.getUserId());
        redisUtil.del("token:" + sysUser.getToken());
        return ResponseResultVO.successResult("成功");
    }

    @Override
    public ResponseResultVO sysUserLogin(SysUserLoginRO sysUserRO) {
        if (StrUtil.isEmpty(sysUserRO.getLoginName())) {
            return ResponseResultVO.failResult("账户名不能为空", "");
        }

        if (StrUtil.isEmpty(sysUserRO.getPassword())) {
            return ResponseResultVO.failResult("密码不能为空", "");
        }

        QueryWrapper<SysUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("login_name", sysUserRO.getLoginName());
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper);

        if (sysUser == null) {
            return ResponseResultVO.failResult("用户名或密码错误", "");//虚假提示
        }
//        if (sysUser.getErrorCount() > 3) {
//            return ResponseResultVO.failResult("禁止登陆，请联系管理员", "");//虚假提示
//        }
        if (!(sysUserRO.getPassword()).equals(sysUser.getPassword())) {
            //密码错误
            //用户存在密码输入错误
//            SysUser dto = new SysUser();
//            dto.setId(sysUser.getId());
//            dto.setErrorCount(sysUser.getErrorCount() + 1);
//            sysUserMapper.updateById(dto);
            log.info("用户:" + sysUserRO.getLoginName() + "用户名或密码错误," + "当前时间:" + DateUtil.parseDateToStr(new Date(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS) + ",当前IP地址为:" + tokenUtil.getIpAddr());
            return ResponseResultVO.failResult("用户名或密码错误", "");
        }

        String oldToken = sysUser.getToken();

        String token = JwtUtils.createToken(String.valueOf(sysUser.getId()), sysUser.getUserName(), sysUser.getLoginName(), SystemConstant.REDIS_SYS_USER_TYPE, Integer.valueOf(sysConfigService.getConfigValue(SystemConfigConstant.ADMIN_TOKEN_EXPIRE)));
//        String token = "admin" + UUID.randomUUID().toString().replaceAll("-", "");
        //更新登录时间以及token
        sysUser.setToken(token);
        sysUser.setLastLoginTime(new Date());
        sysUser.setErrorCount(0);
        sysUserMapper.updateById(sysUser);
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyProperties(sysUser, sysUserVO);
        List<SysRoleVO> roleList = new ArrayList<>();
        //封装用户关联的角色信息
        List<SysUserRole> sysUserRoles = userRoleMapper.selectList(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, sysUser.getId()));
        if (CollectionUtils.isNotEmpty(sysUserRoles)) {
            List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().lambda().in(SysRole::getId, sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList())));
            for (SysRole role : sysRoles) {
                SysRoleVO sysRoleVO = new SysRoleVO();
                BeanUtils.copyProperties(role, sysRoleVO);
                roleList.add(sysRoleVO);
            }
        }
        sysUserVO.setRoleList(roleList);
        sysUserVO.setPassword("");
        sysUserVO.setTenantId(sysUser.getTenantId());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userInfo", sysUserVO);
        resultMap.put("userType", SystemConstant.REDIS_SYS_USER_TYPE);
        if (StringUtils.isNotBlank(sysUserRO.getLoginSite()) && "1".equals(sysUserRO.getLoginSite())) {
            ThreadPoolUtil.execute(() -> {
                ShiftManagement shiftManagement = new ShiftManagement();
                shiftManagement.setDutyUserId(sysUser.getId());
                shiftManagement.setDutyUserName(sysUser.getLoginName());
                baseApiServiceFeign.insertShiftManagement(shiftManagement);
            });
        }
        //清除旧token
//        if (StrUtil.isNotEmpty(oldToken) && redisUtil.hasKey("token:" + oldToken)) {
//            redisUtil.del("token:" + oldToken);
//        }
        redisUtil.set(String.valueOf(sysUser.getId()), sysUser.getUserName(), Long.valueOf(sysConfigService.getConfigValue(SystemConfigConstant.ADMIN_TOKEN_EXPIRE)) * 60L);
        redisUtil.hmset("token:" + token, resultMap, Long.valueOf(sysConfigService.getConfigValue(SystemConfigConstant.ADMIN_TOKEN_EXPIRE)));

        return ResponseResultVO.successResult("登录成功", resultMap);
    }

    @Override
    public ResponseResultVO captcha() {
        Map<String, Object> map = new HashMap<>();
        BufferedImage image = verifyCodeUtil.getImage();
        String code = verifyCodeUtil.getText();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        Long client = SnowflakeIdWorker.generateId();
        try {
            ImageIO.write(image, "jpg", bos);
            byte[] imageBytes = bos.toByteArray();
            BASE64Encoder encoder = new BASE64Encoder();
            String imageString = encoder.encode(imageBytes);
            boolean set = redisUtil.set("captcha:" + client, code, 1);
            System.out.println(set);
            map.put("base64Img", "data:image/jpg;base64," + imageString);
            map.put("client", client);
            return ResponseResultVO.successResult(map);
        } catch (Exception ex) {
            return ResponseResultVO.failResult("获取验证码失败");
        } finally {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public ResponseResultVO getUserByToken() {
        String userId = UserUtil.getUserId();
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (ObjectUtil.isNull(sysUser)) {
            return ResponseResultVO.failResult("获取用户失败");
        }
        sysUser.setPassword(null);
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyProperties(sysUser, sysUserVO);
        return ResponseResultVO.successResult(sysUserVO);
    }


}
